<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
 *****************************************************************************
 * Copyright (C) The Apache Software Foundation. All rights reserved.        *
 * _________________________________________________________________________ *
 * This software is published under the terms of the Apache Software License *
 * version 1.1, a copy of which has been included  with this distribution in *
 * the LICENSE file.                                                         *
 *****************************************************************************
-->

<!--
  Logicsheet for adding Externally controled caching to an XSP page.

  This logicsheet allows to use ESI invalidation protocol with XSP pages.

  @author <a href="mailto:mochoa@ieee.org">Marcelo Ochoa</a>
-->

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsp="http://apache.org/xsp"
  xmlns:cache="http://apache.org/cocoon/cache/1.0"
>
<!-- Namespace URI for this logicsheet -->
<xsl:param name="namespace-uri">http://apache.org/cocoon/cache/1.0</xsl:param>

<!-- Include logicsheet common stuff -->

<!--
   Class-level declarations
-->
<xsl:template match="xsp:page">
  <xsp:page>
   <xsl:apply-templates select="@*"/>
   <xsp:structure>
   	<xsp:include>org.apache.cocoon.caching.CacheValidity</xsp:include>
   	<xsp:include>org.apache.cocoon.caching.ExternalCacheValidity</xsp:include>
   	<xsp:include>org.apache.avalon.framework.parameters.Parameters</xsp:include>
   	<xsp:include>org.apache.avalon.framework.parameters.ParameterException</xsp:include>
   	<xsp:include>org.apache.cocoon.components.cache.Server</xsp:include>
   	<xsp:include>org.apache.cocoon.components.cache.ESIKey</xsp:include>
   	<xsp:include>org.apache.cocoon.environment.http.HttpEnvironment</xsp:include>
   	<xsp:include>org.apache.cocoon.environment.SourceResolver</xsp:include>
   	<xsp:include>javax.servlet.http.HttpServletRequest</xsp:include>
   	<xsp:include>javax.servlet.http.Cookie</xsp:include>
   	<xsp:include>java.util.Map</xsp:include>
   </xsp:structure>
   <xsp:logic><![CDATA[
     // Class attributes of cache.xsl logicsheet
     Server cacheServer = null;
     private ESIKey key = null;
     private HttpServletRequest httpRequest = null;

   // Redefined methods by cache.xsl logicsheet (implements required methods for
   // ESI invalidation protocol
   /**
     * Generate the unique key.
     * This key must be unique inside the space of this component.
     *
     * @return The generated key hashes the src
     */
   public long generateKey() {
     try {
       return this.key.getKey();
     } catch (Exception pe) {
       if (getLogger().isDebugEnabled())
         getLogger().debug("generateKey Exception, returning 0",pe);
       return 0;
     }
   }

   /**
     * Generate the validity object.
     *
     * @return The generated validity object or <code>null</code> if the
     *         component is currently not cacheable.
     */
   public CacheValidity generateValidity() {
      return new ExternalCacheValidity(this.key);
   }

   public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
       throws ProcessingException, SAXException, IOException {
     String cacheControlStr;
     super.setup(resolver, objectModel, src, par);
     try {
        this.cacheServer = (Server)this.manager.lookup(Server.ROLE);
     } catch (ComponentException ce) {
        throw new ProcessingException("Can't get External invalidator server instance");
     }
     // ensure that we are running in a servlet environment
     this.httpRequest =
            (HttpServletRequest)objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
     if (this.httpRequest == null) {
          throw new ProcessingException("HttpServletRequest object not available");
     }
     try {
       this.key = new ESIKey(this.request.getServletPath(), this.parameters, this.httpRequest);
     } catch (ParameterException pe) {
        throw new ProcessingException("Can't encode the url",pe);
     }
    }
   ]]></xsp:logic>
   <xsl:apply-templates/>
  </xsp:page>
</xsl:template>

  <!-- register the current page as external invalidated -->
	<xsl:template match="cache:registerPage">		
          <xsp:logic><![CDATA[
             try {
     	         this.cacheServer.registerCacheablePage(this.key);
             } catch (Exception e) {
               throw new ProcessingException("cache.xsl logicsheet cache:registerPage",e);
             }
           ]]></xsp:logic>		
	</xsl:template>	

	<xsl:template match="@*|*|text()|processing-instruction()">
	    <xsl:copy>
	      <xsl:apply-templates select="@*|*|text()|processing-instruction()"/>
	    </xsl:copy>
	</xsl:template>
</xsl:stylesheet>
